package com.by.gatewayhelper.support;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import com.by.redis.enums.ByRedisUtilityEnum;
import com.by.redis.support.ByRedisSupport;
import com.by.toolkit.consts.RedisConst;
import com.by.toolkit.platform.ByContext;
import com.by.toolkit.utils.SplitterUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Optional;

import static com.by.toolkit.utils.ExceptionUtil.nullError;
import static com.by.toolkit.utils.ExceptionUtil.throwError;

@Slf4j
@Component
public class UserIdSupport {

    @Resource
    private ByRedisSupport byRedisSupport;

    public void setStartUserId(Long userId) {
        Long projectId = ByContext.getProjectId();
        nullError(userId, "用户id不能为空");
        nullError(projectId, "项目id不能为空");
        StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(ByRedisUtilityEnum.COMMON);
        redisTemplate.opsForHash().put(RedisConst.START_USER_ID_HASH_KEY, projectId.toString(), userId.toString());
    }

    public void setDisabledUserId(Long userId) {
        Long projectId = ByContext.getProjectId();
        nullError(projectId, "项目id不能为空");
        Long bit = getUserIdBit(userId, projectId);
        String setDisabledUserIdKey = SplitterUtil.EN_COLON_JOINER.join(RedisConst.SET_DISABLED_USER_ID_BIT, projectId);
        StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(ByRedisUtilityEnum.COMMON);
        redisTemplate.opsForValue().setBit(setDisabledUserIdKey, bit, Boolean.TRUE);
    }

    public Boolean checkDisabledUserId(Long userId, Long projectId) {
        projectId = Objects.isNull(projectId) ? ByContext.getProjectId() : projectId;
        nullError(projectId, "项目id不能为空");
        Long bit = getUserIdBit(userId, projectId);
        String setDisabledUserIdKey = SplitterUtil.EN_COLON_JOINER.join(RedisConst.SET_DISABLED_USER_ID_BIT, projectId);
        StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(ByRedisUtilityEnum.COMMON);
        Boolean disabledBit = redisTemplate.opsForValue().getBit(setDisabledUserIdKey, bit);
        if (BooleanUtil.isTrue(disabledBit)) {
            log.info("[UserIdSupport][checkDisabledUserId] userId:[{}] projectId:[{}] disabledTrue", userId, projectId);
        }
        return disabledBit;
    }

    private Long getUserIdBit(Long userId, Long projectId) {
        StringRedisTemplate redisTemplate = byRedisSupport.getStringRedisTemplate(ByRedisUtilityEnum.COMMON);
        Object value = redisTemplate.opsForHash().get(RedisConst.START_USER_ID_HASH_KEY, projectId.toString());
        if (Objects.isNull(value)) {
            log.error("[UserIdSupport][setDisabledUserId] 项目用户起始id不存在,projectId:{}", projectId);
            throwError("项目用户起始id不存在");
        }
        Boolean isNumber = Optional.ofNullable(value).map(Object::toString).map(NumberUtil::isNumber).isPresent();
        if (!isNumber) {
            log.error("[UserIdSupport][setDisabledUserId] 项目用户起始id格式不正确,startUserId:{},projectId:{}", value, projectId);
            throwError("");
        }
        Long startUserId = Long.parseLong(value.toString());
        Long bit = userId - startUserId;
        log.info("[UserIdSupport][setDisabledUserId] 用户比特位数据,userId:{},bit:{}", userId, bit);
        return bit;
    }

}
